package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os/exec"
	"time"

	"github.com/gorilla/mux"
)

// appMessages - appMessages
type appMessages struct {
	Id      int    `json:"Id"`
	Name    string `json:"Name"`
	Version string `json:"Version"`
}

type PushMessageGitee struct {
	HookName  string `json:"hook_name"`
	Password  string `json:"password"`
	HookID    int    `json:"hook_id"`
	HookURL   string `json:"hook_url"`
	Timestamp string `json:"timestamp"`
	Sign      string `json:"sign"`
	Ref       string `json:"ref"`
	Before    string `json:"before"`
	After     string `json:"after"`
	Created   bool   `json:"created"`
	Deleted   bool   `json:"deleted"`
	Compare   string `json:"compare"`
	Commits   []struct {
		ID        string    `json:"id"`
		TreeID    string    `json:"tree_id"`
		Distinct  bool      `json:"distinct"`
		Message   string    `json:"message"`
		Timestamp time.Time `json:"timestamp"`
		URL       string    `json:"url"`
		Author    struct {
			Time     time.Time `json:"time"`
			Name     string    `json:"name"`
			Email    string    `json:"email"`
			Username string    `json:"username"`
			UserName string    `json:"user_name"`
			URL      string    `json:"url"`
		} `json:"author"`
		Committer struct {
			Name     string `json:"name"`
			Email    string `json:"email"`
			Username string `json:"username"`
			UserName string `json:"user_name"`
			URL      string `json:"url"`
		} `json:"committer"`
		Added    interface{} `json:"added"`
		Removed  interface{} `json:"removed"`
		Modified []string    `json:"modified"`
	} `json:"commits"`
	HeadCommit struct {
		ID        string    `json:"id"`
		TreeID    string    `json:"tree_id"`
		Distinct  bool      `json:"distinct"`
		Message   string    `json:"message"`
		Timestamp time.Time `json:"timestamp"`
		URL       string    `json:"url"`
		Author    struct {
			Time     time.Time `json:"time"`
			Name     string    `json:"name"`
			Email    string    `json:"email"`
			Username string    `json:"username"`
			UserName string    `json:"user_name"`
			URL      string    `json:"url"`
		} `json:"author"`
		Committer struct {
			Name     string `json:"name"`
			Email    string `json:"email"`
			Username string `json:"username"`
			UserName string `json:"user_name"`
			URL      string `json:"url"`
		} `json:"committer"`
		Added    interface{} `json:"added"`
		Removed  interface{} `json:"removed"`
		Modified []string    `json:"modified"`
	} `json:"head_commit"`
	TotalCommitsCount  int  `json:"total_commits_count"`
	CommitsMoreThanTen bool `json:"commits_more_than_ten"`
	Repository         struct {
		ID       int    `json:"id"`
		Name     string `json:"name"`
		Path     string `json:"path"`
		FullName string `json:"full_name"`
		Owner    struct {
			ID        int    `json:"id"`
			Login     string `json:"login"`
			AvatarURL string `json:"avatar_url"`
			HTMLURL   string `json:"html_url"`
			Type      string `json:"type"`
			SiteAdmin bool   `json:"site_admin"`
			Name      string `json:"name"`
			Email     string `json:"email"`
			Username  string `json:"username"`
			UserName  string `json:"user_name"`
			URL       string `json:"url"`
		} `json:"owner"`
		Private           bool        `json:"private"`
		HTMLURL           string      `json:"html_url"`
		URL               string      `json:"url"`
		Description       string      `json:"description"`
		Fork              bool        `json:"fork"`
		CreatedAt         time.Time   `json:"created_at"`
		UpdatedAt         time.Time   `json:"updated_at"`
		PushedAt          time.Time   `json:"pushed_at"`
		GitURL            string      `json:"git_url"`
		SSHURL            string      `json:"ssh_url"`
		CloneURL          string      `json:"clone_url"`
		SvnURL            string      `json:"svn_url"`
		GitHTTPURL        string      `json:"git_http_url"`
		GitSSHURL         string      `json:"git_ssh_url"`
		GitSvnURL         string      `json:"git_svn_url"`
		Homepage          interface{} `json:"homepage"`
		StargazersCount   int         `json:"stargazers_count"`
		WatchersCount     int         `json:"watchers_count"`
		ForksCount        int         `json:"forks_count"`
		Language          string      `json:"language"`
		HasIssues         bool        `json:"has_issues"`
		HasWiki           bool        `json:"has_wiki"`
		HasPages          bool        `json:"has_pages"`
		License           interface{} `json:"license"`
		OpenIssuesCount   int         `json:"open_issues_count"`
		DefaultBranch     string      `json:"default_branch"`
		Namespace         string      `json:"namespace"`
		NameWithNamespace string      `json:"name_with_namespace"`
		PathWithNamespace string      `json:"path_with_namespace"`
	} `json:"repository"`
	Sender struct {
		ID        int    `json:"id"`
		Login     string `json:"login"`
		AvatarURL string `json:"avatar_url"`
		HTMLURL   string `json:"html_url"`
		Type      string `json:"type"`
		SiteAdmin bool   `json:"site_admin"`
		Name      string `json:"name"`
		Email     string `json:"email"`
		Username  string `json:"username"`
		UserName  string `json:"user_name"`
		URL       string `json:"url"`
	} `json:"sender"`
	Enterprise struct {
		Name string `json:"name"`
		URL  string `json:"url"`
	} `json:"enterprise"`
}

func hookGit(w http.ResponseWriter, r *http.Request) {
	var err error
	NewMsg := PushMessageGitee{}

	json.NewDecoder(r.Body).Decode(&NewMsg)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	log.Printf("Person: %+v", NewMsg)

	log.Printf(NewMsg.HookName, NewMsg.Password)
}

func appUpgrade(w http.ResponseWriter, r *http.Request) {
	var err error
	NewMsg := appMessages{}
	json.NewDecoder(r.Body).Decode(&NewMsg)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	log.Printf("Person: %+v", NewMsg)

	app := "/usr/bin/ssh"
	arg0 := "root@docker1.example.com"
	arg1 := "/root/upgrade.sh"
	arg2 := NewMsg.Name
	arg3 := NewMsg.Version

	cmd := exec.Command(app, arg0, arg1, arg2, arg3)
	fmt.Println(cmd.String())
	stdout, err := cmd.Output()

	if err != nil {
		fmt.Println(err.Error())
		return
	}

	// Print the output
	fmt.Println(string(stdout))
}

func main() {
	routes := mux.NewRouter()
	routes.HandleFunc("/api/app", appUpgrade).Methods("POST")
	routes.HandleFunc("/hook/gitee", hookGit).Methods("POST")
	http.Handle("/", routes)
	http.ListenAndServe(":8001", nil)
}
